﻿using System;
using System.Globalization;
using BattleFury.Cartographer.Builder;
using BattleFury.Data;
using BattleFury.Lib;
using BattleFury.Lib.Graphics;
using BattleFury.Lib.Lights;
using BattleFury.Lib.Maps;
using BattleFury.Lib.Tiles;
using BattleFury.Lib.Time;
using Microsoft.Xna.Framework;

namespace BattleFury
{
	public class BattleFuryWorld
		: World
	{
		private Random _rnd = new Random();

		public Camera Camera { get; set; }

		public BattleFuryWorld()
		{
			WorldTime = new BattleFuryWorldTime
			{
				Interval = 250,
				Hour = 12,
			};
			Camera = new Camera
			{
				Size = RenderEngine.Get().Resolution
			};
		}

		public void GenerateChunk()
		{
			var engine = RenderEngine.Get();

			// Initialization and Settings
			WorldBuilder.Initialize(engine.GraphicsDevice);
			WorldBuilder.Settings.Width = (int)ChunkSize.X;
			WorldBuilder.Settings.Height = (int)ChunkSize.Y;

			// Generate Height and Visualization Map
			var heightMap = WorldBuilder.HeightMap;
			var visualizationMap = WorldBuilder.BuildVisualizationTexture(VisualizationScale.Land);

			// Build Map
			var tileMap = WorldBuilder.BuildTileMap();
			var tileset = RenderData.Tilesets["DefaultTileset"];
			var detailTileset = RenderData.Tilesets["DefaultDetailTileset"];

			// Apply Tileset
			var groundLayer = (TileLayer) tileMap.GetLayer("Ground");
			if (groundLayer != null)
			{
				for (var y = 0; y < WorldBuilder.Settings.Height; y++)
				{
					for (var x = 0; x < WorldBuilder.Settings.Width; x++)
					{
						var tile = groundLayer[x, y];
						if (tile != null)
						{
							tile.Tileset = tileset;
							if(tile.Tint == new Color(0, 0, 128)) { tile.Index = 1; }
							else if(tile.Tint == new Color(0, 0, 192)) { tile.Index = 1; }
							else if (tile.Tint == new Color(0, 0, 255)) { tile.Index = 1; }
							else if (tile.Tint == new Color(0, 128, 0)) { tile.Index = 2; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(64, 192, 64)) { tile.Index = 3; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(76, 255, 0)) { tile.Index = 4; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(86, 72, 0)) { tile.Index = 5; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(127, 106, 0)) { tile.Index = 6; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(128, 128, 128)) { tile.Index = 7; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(160, 160, 160)) { tile.Index = 8; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(192, 192, 192)) { tile.Index = 9; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(255, 255, 255)) { tile.Index = 10; tile.Tint = Color.White; }
						}
					}
				}
			}

			var detailLayer = (TileLayer) tileMap.GetLayer("Detail");
			if (detailLayer != null)
			{
				for (var y = 0; y < WorldBuilder.Settings.Height; y++)
				{
					for (var x = 0; x < WorldBuilder.Settings.Width; x++)
					{
						var tile = detailLayer[x, y];
						if (tile != null)
						{
							tile.Tileset = detailTileset;
							var freq = _rnd.Next(0, 100);
							var offset = _rnd.Next(0, 32) * 32;
							var opp = 1;
							if (freq >= 12) opp = -1;
							if (tile.Tint == new Color(0, 128, 0)) { tile.Index = 2 + offset * opp; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(64, 192, 64)) { tile.Index = 3 + offset * opp; ; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(76, 255, 0)) { tile.Index = 4 + offset * opp; ; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(86, 72, 0)) { tile.Index = 5 + offset * opp; ; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(127, 106, 0)) { tile.Index = 6 + offset * opp; ; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(128, 128, 128)) { tile.Index = 7 + offset * opp; ; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(160, 160, 160)) { tile.Index = 8 + offset * opp; ; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(192, 192, 192)) { tile.Index = 9 + offset * opp; ; tile.Tint = Color.White; }
							else if (tile.Tint == new Color(255, 255, 255)) { tile.Index = 10 + offset * opp; ; tile.Tint = Color.White; }
						}
					}
				}
			}


			// Set Light Layer
			var lightLayer = (LightLayer)tileMap.GetLayer("Lights");
			if (lightLayer != null)
			{
				foreach (var bot in RenderData.Bots)
				{
					var light = lightLayer.AddLight(bot.Id.ToString(), Color.Yellow, 128f, bot.Position);
					light.Offset = bot.Size / 2;
				}

				foreach (var player in RenderData.Players)
				{
					var light = lightLayer.AddLight(player.Id.ToString(), Color.Yellow, 128f, player.Position);
					light.Offset = player.Size / 2;
				}
			}

			// Set Chunk
			var chunkLoc = NextAvailableChunk();
			Chunks.Add(chunkLoc, tileMap);

			// Adjust Camera
			var cx = WorldBuilder.Settings.Width * RenderData.TileSize.X - engine.Resolution.X;
			var cy = WorldBuilder.Settings.Height * RenderData.TileSize.Y - engine.Resolution.Y;
			Camera.UpperBounds = new Vector2(cx, cy);
		}

		public override void Update(GameTime gameTime)
		{
			var map = (TileMap)CurrentChunk;
			if (map == null) return;

			map.Camera = Camera;

			var lightLayer = (LightLayer)map.GetLayer("Lights");
			if (lightLayer != null)
			{
				foreach (var player in RenderData.Players)
				{
					player.Update(gameTime);
					lightLayer[player.Id.ToString(CultureInfo.InvariantCulture)].Position = player.Position;
				}

				foreach (var bot in RenderData.Bots)
				{
					bot.Update(gameTime);
					lightLayer[bot.Id.ToString(CultureInfo.InvariantCulture)].Position = bot.Position;
				}

				lightLayer.AmbientLightColor = ((BattleFuryWorldTime)WorldTime).LightColor.Color;
				lightLayer.Update(gameTime);
			}

			base.Update(gameTime);
		}
	}
}